package com.abel.demo.config.security;

import com.abel.demo.utils.BaseUtil;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Iterator;

/**
 * Author: Abel.lin
 * Date: Created in 2018/7/17 16:11
 * Company: Abel.Studio
 * Copyright: Copyright (c) 2017
 * Description:
 */
@Component
public class AccessDecisionManagerImpl implements AccessDecisionManager {

    /**
     * @author: Abel.lin
     * @date: 2018/7/17 16:13
     * @description: 判定是否拥有权限的决策方法,此方法是为了判定用户请求的url 是否在权限表中，
     *                 如果在权限表中，则返回给 decide 方法，用来判定用户是否有此权限。如果不在权限表中则放行。
     * @param authentication 是UserSecurityService中循环添加到 GrantedAuthority 对象中的权限信息集合.
     * @param obj 包含客户端发起的请求的request信息，可转换为 HttpServletRequest request = ((FilterInvocation) obj).getHttpRequest();
     * @param collection 为FilterInvocationSecurityMetadataSourceImpl的getAttributes(Object object)这个方法返回的结果
     * @return:
     */
    @Override
    public void decide(Authentication authentication, Object obj, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
        if(BaseUtil.isEmpty(collection)){
            return;
        }
        ConfigAttribute cfgAttr;
        String roleCode;
        for(Iterator<ConfigAttribute> iter = collection.iterator(); iter.hasNext();){
            cfgAttr = iter.next();
            roleCode = cfgAttr.getAttribute();
            for(GrantedAuthority ga : authentication.getAuthorities()){
                if(roleCode.trim().equals(ga.getAuthority())) {
                    return;
                }
            }
        }
        throw new AccessDeniedException("no right");
    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
